package com.zhu.classfile.attribute.factory;

import com.zhu.classfile.attribute.*;
import com.zhu.classfile.constant.ConstantPool;

import java.nio.ByteBuffer;

public class AttributeInfoFactory {

    /**
     * 读取属性数组
     */
    public static AttributeInfo[] readAttributes(ByteBuffer reader, ConstantPool cp,int attributesCount) {
        AttributeInfo[] attributes = new AttributeInfo[attributesCount];
        for (int i = 0; i < attributesCount; i++) {
            attributes[i] = readAttribute(reader, cp);
        }
        return attributes;
    }

    /**
     * 读取单个属性
     */
    public static AttributeInfo readAttribute(ByteBuffer reader, ConstantPool cp) {
        //所有的AttributeInfo公共部分都是attrNameIndex和attrLen
        int attrNameIndex = Short.toUnsignedInt(reader.getShort());
        // 假设 ConstantPool 有此方法
        String attrName = cp.getUtf8(attrNameIndex);
        int attrLen = reader.getInt();
        // 使用工厂创建实例
        AttributeInfo attrInfo = createAttributeInfo(attrName, attrLen, cp);

        // 调用 readInfo 读取具体内容
        attrInfo.readInfo(reader);

        return attrInfo;
    }



    /**
     * 创建指定类型的 AttributeInfo
     *
     * @param attrName 属性名，如 "Code", "LineNumberTable"
     * @param attrLen  属性长度
     * @param cp       常量池（部分属性需要）
     * @return AttributeInfo 实例
     */
//    public static AttributeInfo createAttributeInfo(String attrName, int attrLen, ConstantPool cp) {
//        return switch (attrName) {
//            case "Code" -> new CodeAttribute(cp); // 需要 cp
//            case "ConstantValue" -> new ConstantValueAttribute(cp);
//            case "Deprecated" -> new DeprecatedAttribute();
//            case "Exceptions" -> new ExceptionsAttribute();
//            case "LineNumberTable" -> new LineNumberTableAttribute();
//            case "LocalVariableTable" -> new LocalVariableTableAttribute();
//            case "SourceFile" -> new SourceFileAttribute(cp); // 需要 cp
//            case "Synthetic" -> new SyntheticAttribute();
//            default -> new UnparsedAttribute(attrName, attrLen);
//        };
//    }

    public static AttributeInfo createAttributeInfo(String attrName, int attrLen, ConstantPool cp) {
        AttributeInfo result = null;
        switch (attrName) {
            case "Code":
                result = new CodeAttribute(cp);
                break;
            case "ConstantValue":
                result = new ConstantValueAttribute(cp);
                break;
            case "Deprecated":
                result = new DeprecatedAttribute();
                break;
            case "Exceptions":
                result = new ExceptionsAttribute();
                break;
            case "LineNumberTable":
                result = new LineNumberTableAttribute();
                break;
            case "LocalVariableTable":
                result = new LocalVariableTableAttribute();
                break;
            case "SourceFile":
                result = new SourceFileAttribute(cp);
                break;
            case "Synthetic":
                result = new SyntheticAttribute();
                break;
            default:
                result = new UnparsedAttribute(attrName, attrLen);
        }
        return result;
    }

}
